{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Deep Neural Network (DNN) \n",
    "\n",
    "### Regularization of DNN [256,256,256,256] with l1 regularization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_32test_std              -> defaultdict(<class 'list'>, {0: array([[ 0.7957011\n",
      "X_32train_std             -> array([[-0.44445615,  0.62874736, -0.19049071, ...\n",
      "X_test                    -> defaultdict(<class 'list'>, {0: array([[[-0.004097\n",
      "X_test_std                -> defaultdict(<class 'list'>, {0: array([[ 0.8784659\n",
      "X_train                   -> array([[[-0.00304779,  0.0030504 , -0.00249425, ..\n",
      "X_train_std               -> array([[-0.44445615,  0.62874736, -0.19049071, ...\n",
      "snrs                      -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_32_test                 -> defaultdict(<class 'list'>, {0: array([6, 7, 1, ..\n",
      "y_32_train                -> array([7, 2, 4, ..., 5, 5, 3])\n",
      "y_test                    -> defaultdict(<class 'list'>, {0: array([3, 2, 5, ..\n",
      "y_train                   -> array([7, 2, 4, ..., 5, 5, 3])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "from functools import partial\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 32) and labels:  (80000,)\n",
      " \n",
      "Test data:\n",
      "Total 20 (4000, 32) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_32train_std.shape, \"and labels: \", y_32_train.shape)\n",
    "print(\" \")\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_32test_std), X_32test_std[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_32test_std.keys()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# tf.reset_default_graph()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Create validation set required for early stopping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Validation set data (40000, 32) and labels (40000,)\n"
     ]
    }
   ],
   "source": [
    "X_val = []\n",
    "y_val = []\n",
    "\n",
    "X_test_new = defaultdict(list)\n",
    "y_test_new = defaultdict(list)\n",
    "\n",
    "for snr in snrs:\n",
    "    n_test = X_32test_std[snr].shape[0]\n",
    "    X_val.append(X_32test_std[snr][:(n_test*0.5)])\n",
    "    y_val.append(y_32_test[snr][:(n_test*0.5)])\n",
    "    X_test_new[snr] = X_32test_std[snr][(n_test*0.5):]\n",
    "    y_test_new[snr] = y_32_test[snr][(n_test*0.5):]\n",
    "    \n",
    "X_val = np.vstack(np.asarray(X_val))\n",
    "y_val =np.hstack(np.asarray(y_val))\n",
    "\n",
    "print(\"Validation set data\", X_val.shape, \"and labels\", y_val.shape)\n",
    "\n",
    "X_32test_std = X_test_new\n",
    "y_32_test = y_test_new\n",
    "X_32_val = X_val \n",
    "y_32_val = y_val"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Design and train the DNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\tValidation loss: 1.387333\tMinimum loss: 1.387333\tAccuracy on validation set: 0.43\n",
      "1\tValidation loss: 1.322262\tMinimum loss: 1.322262\tAccuracy on validation set: 0.45\n",
      "2\tValidation loss: 1.313022\tMinimum loss: 1.313022\tAccuracy on validation set: 0.45\n",
      "3\tValidation loss: 1.287684\tMinimum loss: 1.287684\tAccuracy on validation set: 0.47\n",
      "4\tValidation loss: 1.236780\tMinimum loss: 1.236780\tAccuracy on validation set: 0.49\n",
      "5\tValidation loss: 1.211587\tMinimum loss: 1.211587\tAccuracy on validation set: 0.50\n",
      "6\tValidation loss: 1.218137\tMinimum loss: 1.211587\tAccuracy on validation set: 0.50\n",
      "7\tValidation loss: 1.189027\tMinimum loss: 1.189027\tAccuracy on validation set: 0.50\n",
      "8\tValidation loss: 1.194236\tMinimum loss: 1.189027\tAccuracy on validation set: 0.50\n",
      "9\tValidation loss: 1.201979\tMinimum loss: 1.189027\tAccuracy on validation set: 0.50\n",
      "10\tValidation loss: 1.185957\tMinimum loss: 1.185957\tAccuracy on validation set: 0.51\n",
      "11\tValidation loss: 1.181638\tMinimum loss: 1.181638\tAccuracy on validation set: 0.51\n",
      "12\tValidation loss: 1.178537\tMinimum loss: 1.178537\tAccuracy on validation set: 0.51\n",
      "13\tValidation loss: 1.169448\tMinimum loss: 1.169448\tAccuracy on validation set: 0.51\n",
      "14\tValidation loss: 1.175007\tMinimum loss: 1.169448\tAccuracy on validation set: 0.51\n",
      "15\tValidation loss: 1.173404\tMinimum loss: 1.169448\tAccuracy on validation set: 0.51\n",
      "16\tValidation loss: 1.169971\tMinimum loss: 1.169448\tAccuracy on validation set: 0.51\n",
      "17\tValidation loss: 1.186446\tMinimum loss: 1.169448\tAccuracy on validation set: 0.51\n",
      "18\tValidation loss: 1.167875\tMinimum loss: 1.167875\tAccuracy on validation set: 0.51\n",
      "19\tValidation loss: 1.174517\tMinimum loss: 1.167875\tAccuracy on validation set: 0.51\n",
      "20\tValidation loss: 1.171137\tMinimum loss: 1.167875\tAccuracy on validation set: 0.51\n",
      "21\tValidation loss: 1.170136\tMinimum loss: 1.167875\tAccuracy on validation set: 0.51\n",
      "22\tValidation loss: 1.187222\tMinimum loss: 1.167875\tAccuracy on validation set: 0.51\n",
      "23\tValidation loss: 1.162537\tMinimum loss: 1.162537\tAccuracy on validation set: 0.51\n",
      "24\tValidation loss: 1.166810\tMinimum loss: 1.162537\tAccuracy on validation set: 0.51\n",
      "25\tValidation loss: 1.172105\tMinimum loss: 1.162537\tAccuracy on validation set: 0.51\n",
      "26\tValidation loss: 1.165230\tMinimum loss: 1.162537\tAccuracy on validation set: 0.51\n",
      "27\tValidation loss: 1.169989\tMinimum loss: 1.162537\tAccuracy on validation set: 0.51\n",
      "28\tValidation loss: 1.166987\tMinimum loss: 1.162537\tAccuracy on validation set: 0.51\n",
      "29\tValidation loss: 1.159723\tMinimum loss: 1.159723\tAccuracy on validation set: 0.52\n",
      "30\tValidation loss: 1.171789\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "31\tValidation loss: 1.169745\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "32\tValidation loss: 1.162428\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "33\tValidation loss: 1.167867\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "34\tValidation loss: 1.161517\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "35\tValidation loss: 1.170889\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "36\tValidation loss: 1.165595\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "37\tValidation loss: 1.165701\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "38\tValidation loss: 1.169349\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "39\tValidation loss: 1.165767\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "40\tValidation loss: 1.168434\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "41\tValidation loss: 1.172526\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "42\tValidation loss: 1.173086\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "43\tValidation loss: 1.168982\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "44\tValidation loss: 1.170023\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "45\tValidation loss: 1.175059\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "46\tValidation loss: 1.165296\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "47\tValidation loss: 1.178174\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "48\tValidation loss: 1.183572\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "49\tValidation loss: 1.177977\tMinimum loss: 1.159723\tAccuracy on validation set: 0.51\n",
      "** EARLY STOPPING ** \n",
      " \n",
      "INFO:tensorflow:Restoring parameters from ./DNN4layer_regtech_l1\n",
      "Training and testing took 2.012459 minutes\n"
     ]
    }
   ],
   "source": [
    "# ----------------- Initialize parameters -----------------------\n",
    "\n",
    "\n",
    "n_hidden1 = 256\n",
    "n_hidden2 = 256\n",
    "n_hidden3 = 256\n",
    "n_hidden4 = 256\n",
    "\n",
    "n_outputs = 8\n",
    "\n",
    "X = tf.placeholder(tf.float32, shape=(None, 32))\n",
    "y = tf.placeholder(tf.int64, shape=(None))\n",
    "training_ = tf.placeholder_with_default(False, shape=[])\n",
    "\n",
    "weight_init = tf.contrib.layers.xavier_initializer()\n",
    "activation_func = tf.nn.elu\n",
    "\n",
    "# ------------------- Define layers -----------------------\n",
    "\n",
    "from tensorflow.contrib.layers import fully_connected\n",
    "\n",
    "scale_val = 0.001\n",
    "new_dense_layer = partial(tf.layers.dense, kernel_initializer = weight_init,\n",
    "                          kernel_regularizer = tf.contrib.layers.l1_regularizer(scale_val), \n",
    "                          activation = activation_func)\n",
    "\n",
    "dense_layer1 = new_dense_layer(X, n_hidden1)\n",
    "\n",
    "dense_layer2 = new_dense_layer(dense_layer1, n_hidden2)\n",
    "\n",
    "dense_layer3 = new_dense_layer(dense_layer2, n_hidden3)\n",
    "\n",
    "dense_layer4 = new_dense_layer(dense_layer3, n_hidden4)\n",
    "\n",
    "logits = tf.layers.dense(dense_layer4, n_outputs)\n",
    "\n",
    "# ----------------- Specify performance measure ----------------------\n",
    "\n",
    "xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)\n",
    "loss = tf.reduce_mean(xentropy)\n",
    "\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "training_op = optimizer.minimize(loss)\n",
    "\n",
    "correct = tf.nn.in_top_k(logits, y, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))\n",
    "        \n",
    "# ------------------ Execution phase ----------------------------------    \n",
    "\n",
    "n_epochs = 1000\n",
    "batch_size = 1024\n",
    "n_train = X_train_std.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "saver = tf.train.Saver()\n",
    "\n",
    "min_loss = np.infty\n",
    "epochs_without_improvement = 0 \n",
    "max_epochs_without_improvement = 20   \n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "start = time()\n",
    "path = \"./DNN4layer_regtech_l1\"\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size) #select random samples to form mini batches   \n",
    "            X_batch, y_batch = X_32train_std[rand_indices], y_32_train[rand_indices]\n",
    "            sess.run(training_op, feed_dict={X: X_batch, y: y_batch,  training_: True})\n",
    "        valid_loss, acc_val = sess.run([loss, accuracy], feed_dict={X: X_32_val, y: y_32_val, training_: True})\n",
    "        \n",
    "        # Early stopping \n",
    "        \n",
    "        if valid_loss < min_loss:\n",
    "            save_path = saver.save(sess, path)\n",
    "            min_loss = valid_loss\n",
    "            epochs_without_improvement = 0\n",
    "        else:\n",
    "            epochs_without_improvement += 1\n",
    "            if epochs_without_improvement > max_epochs_without_improvement:\n",
    "                print(\"** EARLY STOPPING ** \")\n",
    "                break\n",
    "        print(\"{}\\tValidation loss: {:.6f}\\tMinimum loss: {:.6f}\\tAccuracy on validation set: {:.2f}\".format(\n",
    "            epoch, valid_loss, min_loss, acc_val))\n",
    "\n",
    "print(\" \")\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_32test_std[snr], y: y_32_test[snr]})\n",
    "\n",
    "print(\"Training and testing took %f minutes\"%(float(time() - start)/60))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test the DNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DNN's test accuracy on -20 dB SNR samples =  0.125\n",
      "DNN's test accuracy on -18 dB SNR samples =  0.1275\n",
      "DNN's test accuracy on -16 dB SNR samples =  0.139\n",
      "DNN's test accuracy on -14 dB SNR samples =  0.1325\n",
      "DNN's test accuracy on -12 dB SNR samples =  0.1405\n",
      "DNN's test accuracy on -10 dB SNR samples =  0.19\n",
      "DNN's test accuracy on -8 dB SNR samples =  0.2845\n",
      "DNN's test accuracy on -6 dB SNR samples =  0.378\n",
      "DNN's test accuracy on -4 dB SNR samples =  0.402\n",
      "DNN's test accuracy on -2 dB SNR samples =  0.4575\n",
      "DNN's test accuracy on 0 dB SNR samples =  0.5505\n",
      "DNN's test accuracy on 2 dB SNR samples =  0.685\n",
      "DNN's test accuracy on 4 dB SNR samples =  0.813\n",
      "DNN's test accuracy on 6 dB SNR samples =  0.8325\n",
      "DNN's test accuracy on 8 dB SNR samples =  0.845\n",
      "DNN's test accuracy on 10 dB SNR samples =  0.834\n",
      "DNN's test accuracy on 12 dB SNR samples =  0.838\n",
      "DNN's test accuracy on 14 dB SNR samples =  0.8375\n",
      "DNN's test accuracy on 16 dB SNR samples =  0.83\n",
      "DNN's test accuracy on 18 dB SNR samples =  0.839\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"DNN's test accuracy on %d dB SNR samples = \"%(snr), acc_test[snr])   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "##  Visualize DNN's performance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nR/8H0GrXzGKuLUcAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f6c73bc8208>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./DNN4layer_regtech_l1\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.80  0.00   0.00  0.00  0.01   0.08   0.10   0.0\n",
      "BPSK   0.00  0.99   0.00  0.00  0.00   0.00   0.00   0.0\n",
      "CPFSK  0.01  0.00   0.97  0.01  0.00   0.01   0.00   0.0\n",
      "GFSK   0.02  0.00   0.02  0.95  0.00   0.00   0.01   0.0\n",
      "PAM4   0.00  0.02   0.00  0.00  0.98   0.00   0.00   0.0\n",
      "QAM16  0.05  0.00   0.00  0.00  0.00   0.50   0.45   0.0\n",
      "QAM64  0.02  0.00   0.00  0.00  0.00   0.47   0.51   0.0\n",
      "QPSK   0.02  0.00   0.00  0.00  0.00   0.05   0.02   0.9\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAGoCAYAAACXNJbuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XmcHFW5//HPNyEQEgg7IkECEhZlB0FAyARQNtmXS4Io\nXhD1avRe4ae4QQwBAUFFFhW87IhBFEFQAiIkgMAlLGGJhATBkLDKjpBASJ7fH+dMqDQ9k05merqr\n5/vmNS+6qk6ffroz00+dpU4pIjAzM7PG6tPoAMzMzMwJ2czMrCk4IZuZmTUBJ2QzM7Mm4IRsZmbW\nBJyQzczMmoATstkSktRf0nWSXpV0ZRfqOUzS+O6MrREk/VnSZxsdh1lZOSFby8sJb5KkNyQ9LelP\nkj7RDVUfDKwGrBQRhy5pJRFxRUTs0Q3xLERSm6T5kn5XsX+zvP+WGusZLenSRZWLiL0i4rIljdes\nt3NCtpYm6RjgJ8BJwOrA2sDPgX27ofohwLRo7tV1/gXsIGmlwr4jgMe680UkqTvrM+uNnJCtZUka\nBIwBvhIR10bE7IiYFxF/iojjcpmlJZ2ZW86zJP1UUr98rE3STEnHSHo+lzkiH/sBcAIwQtLrkv4z\ntyQvK7z+kNwS7ZO3Py/pH7n8PySNzPuPkHR74Xk7SLpH0iuS/k/S9oVjt0o6UdIduZ7xklbu5GN4\nB7gGaH+tPsB/AL+u+KzOlPSUpNdyb8KOef/uwHeBQ3MPwwOFOE7KcbwJrJv3HZmP/1zSVYX6T5P0\nl5r/8cx6ISdka2XbA8uQElJHvg9sC2wGbJ4ff79wfA1geWBN4AvAzyWtEBE/AH4IjIuIQRFxUS5f\n2VoOAEkDgJ8Bu0fEIGAHYHKVcisB1wNnAqsAPwX+VNHCHUlq5a6W39//6+T9BXAp8Lm8vTvwCPBs\nRbl78mewEnAFcJWkpSPixvw+r4yI5SNiy8JzDs+fyfLAUxX1HQtsKulzknYC/rMQg5lV4YRsrWwV\n4MWImN9JmcOAMRHxUkS8RGpRFycmvQOMzS3rG4B/AxsuYTzzSEmqf0Q8HxGPVinzaVI3+BURMT8i\nxgFTgX0KZS6KiH9ExNvAb4EtOnvRiLgbWEnSBqSk+L7x4Px6r+bX/Ckp0S/qfV4cEVPzc96tqG82\nKWH/NL/eqIioPAkwswInZGtlLwGrtncZd2BNFm7dzcj7FtRRkdDfApZb3EAi4i3gUOC/gGfz7Oxq\nCW/NHEPRDGBwYfu5JYjnMmAUMBz4Q+VBScdK+nvuJn8FGASsuog6Z3Z2MCLuBZ4ABFzVWVkzc0K2\n1nYXMAfYv5MyT5MmZ7UbAjyzhK/3JjCgsP3B4sGI+EtE7EbqBn8MOL9KHc8A61TsWzvH2RWXA18B\n/hQRc4oHcpfyt4CDI2KliFgJeJ2USOH93fAsYn97vV8Flia9p+O6ELtZr+CEbC0rIl4HRgPnStpP\n0rKSlpK0p6RTc7FxwPclrSppVeB4UmtySUwGhkn6kKQVgG+3H5C0uqR98ljyXFLX97wqdfwZWF/S\nCEl9JR0KfAS4bgljAiAi/gkMY+Hx8XbL5ZheypPcTiCNC7d7HlhncWZS5+7xscBnSN3k35S02RKG\nb9YrOCFbS8vjoceQEtELpO7pr/DeRK+TgHuBh4AH8+OTO6uyk9e6Gbgy1zWJhZNoH9JEp6eBF0nJ\n8StV6ngZ2Js0UevF/P9PR8Qri3r9RYmIOyPiuSqHbgTGA9OAJ0nd4MXu6KtIreWXJN3bSRztE9P6\nkk5qTomIRyLiceB7wGXtM9jN7P3U3JdQmpmZ9Q5uIZuZmTUBJ2QzM7Mm4IRsZmbWBJyQzczMmsBS\njQ6gUSR5NpuZWZ1ERFPccKS/Voy3ea2r1cyIiHW6IZxO9dpZ1pLiiJ3O6/Z6J8+4ji2G7LPogovh\nglu+0K31tRtz4hhGnzC6LnV3t94eaz3+Tk88cQwn1OEznTNnbrfX+cMfnsR3v1vtEuqumz+/ez/b\nU045ie98pz6xDhy4TLfWV6+/q6X69W2ahCwp2ji+S3VMZGyPvJ9e20I2M7Peoct3B+2hdqsTspmZ\ntbautm2dkMtpjRU2aHQINWtra2t0CDVzrN2vLHEC7LTTsEaHULMddyxPrGX6HegK9eliRu7sfnHd\nyGPIJVCvMWQrjzL9ndZjDLmeunsMuZ66ewy5XpptDHnnpbo2Tn7ru2M8hmxmZtZVXR1C7ilOyGZm\n1tpKkpGdkM3MrKWVJB97pS4zM7Nm4BaymZm1tC7Psu4hTshmZtbaStJn7YRsZmYtrST52GPIZmZm\nzcAtZDMza2ldXsu6hzghm5lZaytHPnZCNjOz1laWWdZNNYYs6RuSHpH0kKRfS1pG0gRJUyVNlnS7\npPVz2b0l3Z/3PyLp6Lx/tKRj8uP+km6S1LWbYZqZmdVZ07SQJa0JfA3YKCLekXQlMIJ0n42REfFA\nTrqnSzoYOA/4WEQ8K6kfsE5Fff2A3wGTImJsT74XMzNrHiUZQm6uFjLQFxgoaSlgAPA0qfe//eO8\nDRgKLJ/LvgIQEXMjYnqhnn7AOGBaRHyvh2I3M7NmJHXtp4c0TUKOiGeAHwNPkRLxqxFxc0WxfYGH\nI+IV4DpghqQrJB2mhafRfQuYGxHH9ETsZmbWvEqSj5uqy3pFYD9gCPAacJWkz+TDv5Y0G/gnqVub\niDha0pnAJ4Fj8/+PzOVvB7aXtH5Fy3khk2dct+DxGitswBorbtit78nMrDeYMHECEydObHQYpdc0\nCZmUUJ+IiJcBJP0B2AEI4DMRcX/lEyJiCjBF0uXAE7yXkG8DLgFukLRjRDxX7QW3GLJP978LM7Ne\nZnjbcIa3DV+wPXbsiY0LpgrPsl58TwHb5ZnRAnYF/k6VK8gkDZTUVti1JTCjWCYi/gCcDtwoaYX6\nhW1mZk2tJH3WTdNCjoh7JP0OeACYC9wPnA8cVKW4gG9J+iUwG3gTOKJKnedJ+gBwraTdIuKdur0B\nMzNrSmWZZd00CRkgIsYAYyp271Kl3L+BT3dSR3H7RKC5+k/MzMwqNFOXtZmZWbeT1KWfTurdIy9c\nNU3ScVWOry3pZkkPSrolr7fRISdkMzNrberiT7UqpT7AOcDuwMbASEkbVRQ7A7g4IjYn9dSe2lmY\nTshmZtbS1Edd+unAtsD0iJgREXNJi1HtV1Hmo8AtABExocrxhTghm5mZLb7BwMzC9qy8r2gyeWKy\npAOB5SSt1FGFTshmZtba6tBl3cGRqNj+JjBc0n3ATqRVKN/tqMKmmmVtZmbW3TqbmFXNi3P+wYtv\n/2NRxWYBaxe21wKeKRaIiGd5r4U8EDgoIt7oqEInZDMza2mLm5BXW3Yoqy07dMH2tDcqb6sAwCRg\nqKQhwLOkuxOOrHjdVYCXIyKA7wAXdva67rI2MzNbTBExDxgF3ARMAcZFxKOSxkjaOxcbDjwmaSqw\nOnByZ3W6hWxmZq2tTk3PiBgPbFixb3Th8e+B39danxOymZm1tMXtsm4UJ2QzM2tpJcnHHkM2MzNr\nBm4hm5lZaytJE9kJ2czMWlpJ8rETspmZtbZO1qNuKh5DNjMzawK9uoV8wS1faHQINdm13w8aHULN\n/jr3B40OoSWV5bINgGWXXbrRIZgtrCR/P706IZuZWesrST52QjYzs9ZWlh4mjyGbmZk1AbeQzcys\ntZWk6emEbGZmLa0sXdZOyGZm1tLKkpBL0pA3MzNrbW4hm5lZS1NJmp5OyGZm1trcZW1mZma1cgvZ\nzMxaWkkayE7IZmbW2spytycnZDMza20laSJ7DNnMzKwJuIVsZmYtrSQNZCdkMzNrbR5DNjMzawYl\naSI3zRiypHmS7pc0WdK9krbL+4dIeisfe0TSL/J+SfqZpIclPSTp/yQNyceelLRyfry1pCckbd64\nd2dmZta5ZmohvxkRWwFI2g04FRiejz0eEVtJ6gvcIml/oD/wwYjYND9nTeDNXD7yvs2Aq4BDIuLB\nHnsnZmbWNOrVQJa0B3AmqXF7QUScVnH8Q8AlwIq5zHci4oaO6mumhFz8yFYAXq4sEBHzJN0JDAXm\nAc8Wjj1TUfyjpA/iMxFxX/eHa2ZmZVCPMWRJfYBzgF2BZ4BJkq6NiKmFYt8HroyI8yR9BPgzsG5H\ndTZTQl5W0v3AssAawC6FYwKQNID05o8HHgHukLQTcAtweURMLpS/Bjg8Iu7qofjNzKwZ1aeFvC0w\nPSJmAEgaB+wHFBPyfGBQfrwi8HRnFTZTQn6r0GW9HXAZsEk+tl5O1gFcExE35nIbkBL3rsDNkg6J\niFvzc24GjpZ0Y0REtRccc+KYBY/b2toY3ja8+9+VmVmLmzBxAhMnTmx0GD1tMDCzsD2LlKSLxgA3\nSfo6MAD4ZGcVNlNCXiAi7pa0qqRV867H25N1Rbm5wI3AjZKeB/YHbiUl7lHAecAvgC9Xe53RJ4yu\nR/hmZr3K8LbhCzVoxo49sXHBVKH6DCJXq7Sy8TcSuCgifpobmpcDG3dUYTMl5AVvTtJGpAHwl4CB\nVHnjkrYEnouIZ3Nf/mZAsct6PunDGC9pTEQ4+5qZ9UKLO4b87KuP8dyrjy2q2Cxg7cL2WqSx5KKj\ngN1hQUOzv6RVI+LFahU2U0Lun7ul2z+5z0VE5DObal3OqwO/krR03r4HODc/DoCIeCfPyJ4g6bmI\n+EX9wjczs2a0uA3kNVfakDVX2nDB9oNPXV+t2CRgaL7c9llgBKkRWDSD1E19SZ7UtUxHyRiaKCFH\nRL8O9s8gtX4r999I6q6u9pwPFx6/Dryvu9vMzGxJ5at+RgE38d5lT49KGgNMiojrgf9Hajh+g9Rr\ne0RndTZNQjYzM6uLOl2IHBHjgQ0r9o0uPH4U2LHW+pyQzcyspXktazMzsyZQkqWsm2ctazMzs97M\nLWQzM2ttJWkiOyGbmVlLq9PCIN3OCdnMzFqaSjI4W5IwzczMWptbyGZm1trcZW1mZtZ4JcnHTshm\nZtbayrIwiMeQzczMmoBbyGZm1tpK0mfthGxmZi2tJPnYCdnMzFqbx5DNzMysZr26hRwRjQ6hJn+d\n+4NGh1Cz3Qae2OgQanbjv49vdAg1K8vSf1Cev6t2ZfpsbQmV5N+4VydkMzNrfSXJx07IZmbW2jyG\nbGZmZjVzC9nMzFpaWeYJOCGbmVlrK0c+dkI2M7PW5jFkMzMzq5lbyGZm1tI8hmxmZtYMStJl7YRs\nZmYtrSQNZI8hm5mZLQlJe0iaKmmapOOqHP+JpAck3S/pMUkvd1afW8hmZtbS6jGGLKkPcA6wK/AM\nMEnStRExtb1MRBxTKD8K2KKzOt1CNjOz1tZHXfupbltgekTMiIi5wDhgv06iGAn8prMw3UI2M7OW\nVqcx5MHAzML2LFKSrvL6WhtYB7ilswqdkM3MzApmPjeFWc9NWVSxamm+o3uPjgB+F4u4N6kTspmZ\ntbTFXalr7TU3Ye01N1mwffeDv6tWbBawdmF7LdJYcjUjgK8s6nWdkM3MrLXVp896EjBU0hDgWVLS\nHfn+l9aGwIoRcfeiKuzxSV2SPiDpN5KmS5ok6XpJ60t6K08Nf0TSz3PZIYX97VPHl5K0uqTrJE2W\nNEXS9YXyDxde62hJ90paoaffp5mZta6ImAeMAm4CpgDjIuJRSWMk7V0oOoI04WuRGtFC/gNwUUSM\nBJC0KfAB4PGI2EpSX+AWSfsDD7TvL1Yg6UTgpog4O29vUjgced9nga8CO0fEa/V+U2Zm1pzqtXRm\nRIwHNqzYN7pie0yt9fVoC1nSzsA7EfGr9n0R8TCFmWr5rONOYGj706pU9UFS/337cx5Z+GV0CPAt\n4FMR8Ur3vQMzMysb9enaT0/p6S7rTYD7OjgmAEkDSBdat3c9r5e7qu+XdHbedy5woaS/SvqupA8W\n6hkCnA3sFhH/6v63YGZmZSKpSz89pZkmda0n6X5Sl/M1EXFjHix/X5d1RNwkaV1gD2Av4P5Ct/W/\ngJeAQ4EzO3vBE098ryehra2Ntrbh3fVezMx6jQkTJzBx4sRGh1F6PZ2QpwAHd3DsfYm3MxHxKmmg\nfJyk64BhwP3Am8CewN8kvRARV3RUxwknjO7okJmZ1Wh423CGFxo0Y8ee2LhgqinJ3SV6tMs6Im4B\nlpZ0VPu+PKnrQ5087X2fpKSdJS2bHy8PrAc81X44Il4itZ5PlrRbd8VvZmbl4zHkjh0A7Cbp8XyJ\n0g+B5zopX21lk62BeyVNBv4GnB8R9xXLR8Q/SeuKXiBpm+4K3szMysVjyB2IiOdI47uVNqtSdkYH\n+88AzlhU+Yh4iM5b32ZmZk2hmSZ1mZmZdb/FXDqzUZyQzcyspfVkt3NXOCGbmVlLK0k+bsikLjMz\nM6vgFrKZmbU2jyGbmZk1nseQzczMmkBJ8rHHkM3MzJqBW8hmZtbaPIZsZmbWeB5DNjMzawIqSQvZ\nY8hmZmZNwC1kMzNrbeVoIDshm5lZa/MYspmZWRPwGLKZmZnVrFe3kOfPj0aHUJO+fctxdgdww+vf\nb3QINdtr5R82OoSa3fDK9xodQs3K0j3YLqIc3wNQvs+2WZTlc+vVCdnMzHqBcuRjJ2QzM2ttZWkh\newzZzMxsCUjaQ9JUSdMkHddBmf+QNEXSw5Iu76w+t5DNzKyl1aOBLKkPcA6wK/AMMEnStRExtVBm\nKHAcsH1EvC5p1c7qdAvZzMxamtS1nw5sC0yPiBkRMRcYB+xXUeZo4NyIeB0gIl7sLE4nZDMza2mS\nuvTTgcHAzML2rLyvaANgQ0l3SLpT0u6dxekuazMzs4InnpzMk/98cFHFqmXqymvolgKGAsOAtYHb\nJW3c3mKu5IRsZmYtbXHHkNf78Bas9+EtFmzfOuGyasVmkZJsu7VIY8mVZe6KiPnAPyU9BqwP3Fet\nQndZm5lZS6tTl/UkYKikIZKWBkYAf6wocw2wS45hVVIyfqKjCt1CNjOzllaPWdYRMU/SKOAmUuP2\ngoh4VNIYYFJEXB8RN0raTdIU4F3g/0XEKx3V6YRsZma2BCJiPLBhxb7RFdvHAsfWUp8TspmZtbSy\nrNTlhGxmZi2tJPnYCdnMzFqbSnJ3Cc+yNjMzawJuIZuZWUtzl7WZmVkTKEtCbooua0mrS/q1pMcl\nTZL0N0n7SWqT9Kqk+yU9IOmmXH4DSbfmfVMk/TLvb5N0XaHekyTdIKlfo96bmZk1Vp0WBul2i9VC\nlrQCMDgi/t7NcVwDXBQRn8mv8yFgX+BV4LaI2Lei/FnAjyPi+lx+48KxyPu+B2wP7JnvxGFmZta0\nFtlClvRXSYMkrQRMBi6TdHp3BSBpF+DtiPhV+76ImBkR57YXqfK0NYCnC+WnLFyljgH2APaJiHe6\nK1YzMyufOt1+sdvV0mW9cr4zxYHA5RGxNdDpLaQW08bA/Z0c3yl3Wd8v6Tt535nArZL+JOl/csu9\n3SeAL5Faxm91Y5xmZlZGJcnItXRZLyVpNeAQ4IQ6x4Okc4AdgXeAb1KlyzoiLpY0ntQK3h/4oqTN\n8+HHgRVJJw2/7+y1xo49ccHjYcPaaGtr6663YWbWa0yYOIGJEyc2OozSqyUhnwxMBO6IiHskfRh4\nshtjmAIc1L4REaMkrQLcy/vvLUmh3HPAxcDFkh4GNsmHngMOA26R9FJETOiojuOPr/v5hZlZyxve\nNpzhbcMXbBcbO82gZWZZR8S4iPhoRHwxbz8REft1VwARcQuwjKQvFXYP5L1k/L6PUtLukpbKj9cA\nVmbhMeXHSV3slxVazmZm1guVZZZ1LZO6TsmTupaSdKOk5yUd1s1x7A8Ml/QPSXcDFwHHkZJxtVby\nbsAjkh4AbiDd0uqFYoGIuBc4ErhW0rrdHK+ZmZVESYaQa+qy3jMiviNpf+AZYCRwK3BFdwUREc/n\neqt538BER7ezioiJxfIR8Rdgne6J0szMrH5qmtSV/78XcFVEvCypw7FdMzOzZtJKt1+8QdIjwDzg\nq5JWBd6ub1hmZmbdoyT5uKZJXd8EdgG2zitezSFNmDIzM2t66uJPT6l16cyVgR0l9S/s67YxZDMz\ns95ukQlZ0vdJs5o3Am4kLbhxB07IZmZWAmUZQ65l6cxDgZ2BZyPis8DmpOuEzczMml4rXfY0OyLm\nSXpX0vKklbCG1DkuMzOzblGWFnItCfkBSSsCF5KWs3wduKeuUZmZmfUyi0zIEdG+pOW5km4EBkVE\nZ3dnMjMzaxolaSB3nJAlbdbBoXclbRYRD9UpJjMzs27TCl3W53ZyLIBh3RyLmZlZt6tXPpa0B3Am\naYL0BRFxWsXxI4DTgVl51zkRcWFH9XWYkCNip66Ha2Zm1nok9QHOAXYl3edhkqRrI2JqRdFxEfH1\nWuqs5W5PX86Tutq3V5L0xcWI28zMrGHqdNnTtsD0iJiRV7EcB1S7NXHN7fNarkP+ckS82r4REa8A\n/1XrC5iZmTVSne6HPBiYWdielfdVOlDSZEm/lbRWZ3HWkpD7VryxPkC/Gp5nZmbWcHVqIVc7Unkn\nxD8C60TEFsBfgUs6i7OW65D/Iuk3wC/zi/0XcHMNzzMzMyudqY/dz2PTFnl17yxg7cL2WqSx5AVy\nj3K7XwELTfqqpIjOb20sqS8pCX+SdEZwE3BeRLy7qGibmaR4d+68RodRk3nz5jc6hJr17VtLp4st\nrk8uM6bRIdTs5rdHNzoEa7Cl+vUlIpriWiNJceH5d3epjiO/uN373k/OjY+RJnU9S1owa2REPFoo\ns0ZEPJcfHwB8MyJ26Oh1alkYZB5pJtk5S/JGzMzMGqoOpwZ5SelRpEZq+2VPj0oaA0yKiOuBr0va\nF5gLvAx8vrM6a739opmZWSnVa2GQiBgPbFixb3Th8XeB79Zan/sXzczMmkDNLWRJy0TE2/UMxszM\nrLuVZenMWhYG2VbSw8D0vL25pLPrHpmZmVk3KMv9kGvpsj4L2Bt4CSAiHgR2rmdQZmZm3aVOC4N0\nu1oScp+ImFGxrxzXC5mZmZVELWPIMyVtC0S+7uprwLT6hmVmZtY9SjKEXFNC/i9St/XawPOkVbq8\nlrWZmZVCWSZ11bIwyAvAiB6IxczMrNu1TEKW9Cvev2A2EeFbMJqZmXWTWrqsizeS6A8cwMK3nDIz\nM2taJWkg19RlfWVxW9JlwB11i8jMzKwbtUyXdRXrAh/o7kDMzMzqQX1aJCFLeoX3xpD7kO5Y8e16\nBmVmZtbbdJqQldr5mwNP513zY1E3UDYzM2siJemx7nylrpx8/xwR8/JPtyZjSfMk3S/pYUlXSupf\nOHaApPmSNijsG5L3jSnsW0XSO5LOqqj74Fx2q+6M2czMyqWVls6cXMek9mZEbBURm5Ju4PzlwrER\nwO28/xroJ0hra7c7BHikWEDScqQVxe7u9ojNzKxUSn9zCUnt3dlbAvdIeiy3Zh+QdH8dYrkdGJpf\neyCwA3AUMLKi3Gzg0cJJwqHAbyvKjAVOA3y7SDMzK4XOxpDvAbYC9q3j6wsWJP89gRvy/v2B8RHx\nuKSXJG0REZMLzxsHjJT0PPAu8AywZq5rS2CtiPizpG/WMXYzMyuBVrjsSQAR8Y86vv6yhdb27cAF\n+fFI4Kf58ZXAYUB7Qg5gPHASaW3tK3kvsQv4CXBE4TXK8S9hZmZ10QoJeTVJx3R0MCJ+0g2v/1ZE\nLDQ+LWllYBdgY0kB9CUl4W8VXvtdSfcBxwAb814rfnlgE2BCTs5rANdK2jci3tfNPubEBXPDaGtr\nY3jb8G54S2ZmvcuEiROYOHFio8PoUEnycacJuS+wHPVtYVar+xDgkohYcEcpSbdK+gQwq/CcHwMT\nIuKV9rOfiHgdWK34POCYiHig2ouPPmF0t7wJM7PebHjb8IUaNGPHnti4YEqss4T8bETU+1OtdhnV\nocCpFfuuJnVb/6j9ORHxd+DvNdRfknMjMzOri5I0kRc5hlxPETGoyr5dquw7u7C5WZXjlwCX1FKX\nmZn1Lq0whrxrj0VhZmZWJyXJxx1fhxwRL/dkIGZmZr3ZktztyczMrDTKcrenWpbONDMzK616LZ0p\naQ9JUyVNk3RcJ+VqureCE7KZmdliktQHOAfYnbQexkhJG1UpV/O9FZyQzcyspdXpbk/bAtMjYkZE\nzCUt6bxflXI131vBCdnMzFpanRLyYGBmYXtW3ld83S3I91aoJU5P6jIzs5a2uJc9PfTQPTz88D2L\nrLbKvgWLXeXlm3/KYtxbwQnZzMysYLPNtmWzzbZdsH3FFedWKzYLWLuwvRbpzoPtlieNLdd0bwVw\nQjYzsxZXp5W6JgFDJQ0BngVGkO5UCCy4t8LqhRg6vbcCOCGbmVmLq0dCjoh5kkYBN5HmY10QEY9K\nGgNMiojrK5+Cu6zNzKw3q9fSmRExHtiwYl/V2wjWcm8Fz7I2MzNrAm4hm5lZS2uFuz2ZmZmVnhOy\nmZlZEyhJPvYYspmZWTPo1S3kue+82+gQatJv6V79z2TAzW9XnbjZlC6+YJErHDWV5Qb1b3QINTv4\nkM0aHUIpleX2i/6mNzOzllaWLmsnZDMza2nqfD2OpuExZDMzsybgFrKZmbW2cjSQnZDNzKy1+Tpk\nMzOzJlCSfOwxZDMzs2bgFrKZmbU0d1mbmZk1gZLkYydkMzNrbWVpIXsM2czMrAm4hWxmZi2tJA1k\nJ2QzM2ttZemydkI2M7OWVpJ87DFkMzOzZuAWspmZtTS3kDNJgyVdI2mapMclnSWpX+H4zyTNqnjO\nEZLmS9q5sO+AvO/AvP1VSdMlzZO0csXzh0t6QNIjkm6t93s0M7PmpS7+11N6osv6auDqiNgAWB8Y\nAJwOoDTSvj/wlKRhFc97CBhZ2D4UmFzYvgPYFZhRfJKkFYBzgb0jYhPgkO57K2ZmVjZS1356Sl0T\nsqRdgNkRcSlARATwDeBzkgYAOwMPA78ADqt4+h3AtpL6ShoIDKWQkCPiwYh4ivffWOsw4PcR8XQu\n92L3vzMzM7PuVe8W8sbAfcUdEfEG8CQpwY4ErgCuAT4tqW+xKHAzsAewH3Btja+5AbCypFslTZL0\n2a69BTMzKzNJXfrpKfVOyCIl1mqvuwywF3BtTtL3ALsVygQwDhhB6q7+DbXdZnopYCtgT1IyP17S\n0CV9A2ahDxatAAAgAElEQVRmVm716rKWtIekqXmO1HFVjn9J0kN5TtNtkjbqLM56z7KeAhxU3CFp\nELA68EFgBeDhPJa8LPAmcEN72Yi4V9ImwJsR8XgHZyqVCX8W8K+ImAPMkXQbsDnweOUTTzp57ILH\nw3YaxrBhbYv9Bs3MersJEycwceLERofRoXq0ciX1Ac4hzWV6Bpgk6dqImFoo9uuIOC+X3wf4Kamx\nWFVdE3JE/FXSKZIOj4jLc5f0GaQ3MQI4KiKuzMEOAJ6U1L+imm8Dczp5GbFwy/la4Oz8WssAHwd+\nUu2J3//e8UvytszMrGB423CGtw1fsD127ImNC6bnbAtMj4gZAJLGkYZXFyTkiPh3ofxywPzOKuyJ\nWdYHAIdImga8CMwDziR1T/+pvVBEvAXcDuxTfHJE3BgR7adeC1rDkr4maSYwGHhQ0vm5/FTgRtIs\n7buB8yPi73V6b2Zm1uTq1GU9GJhZ2J6V91W8tr4i6XHgVODrncVZ94VB8mzn/XJg25HGgs+PiFWr\nlD24sHlJleNHFh6fDZzdwWueQWqJm5lZL7e4Xdb33nsn99571yKrrbLvfXOmIuLnwM8ljQCOBz7f\nUYU9ulJXRNwNrNuTr2lmZr3cYg4hf2ybHfjYNjss2D7//KqjnrOAtQvba5HGkjtyJfDLzl7Xa1mb\nmZktvknAUElDJC1Nmhf1x2KBiit89gamdVah17I2M7OWVo9Z1hExT9Io4CZS4/aCiHhU0hhgUkRc\nD4yS9EngHeAV4IjO6nRCNjOzllavtT0iYjywYcW+0YXH/7M49Tkhm5lZS+vJ1ba6wmPIZmZmTcAt\nZDMza2nlaB87IZuZWYsrS5e1E7KZmbW0kuRjjyGbmZk1A7eQzcyspbnL2szMrAmUJB+7y9rMzKwZ\nuIVsZmYtrSwtZCdkMzNraR5DNjMzawIlycceQzYzM2sGvbqF3Kevz0fMulv/Zfs1OoTF8vqrsxsd\ngtVZWbqsnZHMzMyaQK9uIZuZWetzC9nMzMxq5haymZm1tJI0kN1CNjMzawZuIZuZWUtzC9nMzMxq\n5haymZm1NFGOJrITspmZtbZy5GMnZDMza20eQzYzM7OaOSGbmVlLUxf/67BeaQ9JUyVNk3RclePf\nkDRF0mRJf5H0oc7idEI2M7PWpi7+VKtS6gOcA+wObAyMlLRRRbH7ga0jYgvg98DpnYXphGxmZi2t\nDvkYYFtgekTMiIi5wDhgv2KBiJgYEXPy5t3A4M7idEI2MzNbfIOBmYXtWXSecI8CbuisQs+yNjOz\nllanuz1VqzQ6eP3Dga2Bts4qrHtCljQYOBf4KKlF/mfg2NzER9LPgIMiYq3Cc44ALgJ2jYhb874D\nSH3wB0fE1XnfycDBwLvALyLinEId2wB3Af/RXt7MzHqhxczHd911B3fddceiis0C1i5srwU8876X\nlj4JfAcY1p73OtITLeSrgXMjYn+l05RfkQa2/ydv7w88JWlYRNxWeN5DwEjg1rx9KDC5/aCk/wQG\nR8SGeXvVwrE+wKnA+Pq9LTMzK4PFbR/vsP2O7LD9jgu2zzzztGrFJgFDJQ0BngVGkHLWe68rbQn8\nEtg9Il5a1OvWdQxZ0i7A7Ii4FCAiAvgG8DlJA4CdgYeBXwCHVTz9DmBbSX0lDQSGUkjIwJeBE9s3\nIuLFwrGvAb8DXujed2RmZgYRMQ8YBdwETAHGRcSjksZI2jsX+xEwELhK0gOSrumsznq3kDcG7ivu\niIg3JD1JSrAjgSuA64AfSuqb3ySkvvibgT2AFYBrgXULVa0HjMhd2S8A/x0Rj+cu8v2BXUiz4MzM\nrBer0xgyETEe2LBi3+jC408tTn31nmUtqg9y9wGWAfYCro2IN4B7gN0KZYI0jXwEqbv6Nyzc87AM\n8FZEbAP8L3Bh3v9T4LjcGofF760wMzPrcfVuIU8BDirukDQIWB34IKnl+3AeS14WeJPCtPCIuFfS\nJsCbufVbrGomaXyaiPiDpPaE/DFgXK5zVWBPSXMj4o+VwY0du6DHm2HD2mhr63QCnJmZVTFh4gQm\nTpzY6DA6VJa1rPVeQ7JOLyDdA5wVEZdL6ksaL34S2JTUOr4ylxuQ9w8htYi3joivS9odmBMREyVd\nBFwXEVdL+iHpouyLJA0HTouIj1e89oLyVeKKt+d0OuGtafTt68vFrTzGXfFAo0NYLG+9+U6jQ6jZ\nkUd/fNGFmsBS/foSEU2RBiXF07Ne7VIdg9dasUfeT0980x8AHCJpGvAiMA84k9Q9/af2QhHxFnA7\nsE/xyRFxY0S0n3oVzx5OAw6S9BBwMvCFKq9d37MNMzNrepK69NNT6n7ZU0Q8TV5OTNJ2pLHg8yNi\n1SplDy5sXlLl+JGFx68Be1eW6ai8mZlZM+vRlboi4m4WniltZmZWV2UZQ/bgpJmZWRPwWtZmZtbS\nOruncTNxQjYzs9ZWjnzshGxmZq3NY8hmZmZWM7eQzcyspZWkgeyEbGZmLa4kfdZOyGZm1tLKkY49\nhmxmZtYU3EI2M7OWVpIeaydkMzNrcSXJyE7IZmbW0sqRjj2GbGZm1hTcQjYzs5ZWkh5rJ2QzM2t1\n5cjITshmZtbS3EI2s17poIM3bXQIi6VP3/JMpTlw3TMaHYLVUXl+E83MzFqYW8hmZtbSytJl7Ray\nmZlZE3BCNjOzFqcu/nRQq7SHpKmSpkk6rsrxnSTdJ2mupAMXFaUTspmZtTSpaz/V61Qf4Bxgd2Bj\nYKSkjSqKzQCOAH5dS5weQzYzM1t82wLTI2IGgKRxwH7A1PYCEfFUPha1VOgWspmZ2eIbDMwsbM/K\n+5aYW8hmZtba6jPLulqtNbWEO+KEbGZmLU2LmZFvv/02br/jtkUVmwWsXdheC3hm8SJbmBOymZlZ\nwU47DWOnnYYt2D71tJOrFZsEDJU0BHgWGAGM7KTaRZ4VeAzZzMxsMUXEPGAUcBMwBRgXEY9KGiNp\nbwBJH5M0EzgY+KWkhzur0y1kMzNrafVaqSsixgMbVuwbXXh8L/ChWutzC9nMzKwJuIVsZmatrSSL\nWbuFbGZm1gTcQjYzs5ZWjvZxk7SQJQ2WdE1eoPtxSWdJWlpSm6RX8+LcUySdkMsvK+lySQ9JeljS\nbZIG5GNvFOrdS9JjktZq1HszM7MGq8+9JbpdUyRk4Grg6ojYAFgfGAD8KB+7LSK2BrYBDpe0JfDf\nwHMRsVlEbAocBczN5QNA0q7Az4DdI2JWz70VMzNrJiXJx43vspa0CzA7Ii4FiIiQ9A3SXTJuai8X\nEW9Jug9YD1gDeKpwbPrCVWpH4Dxgz4j4Z/3fhZmZWdc0PCGTblt1X3FHRLwh6Z+k1jIAklYBPg6c\nCEwHbpJ0EHALcElEPJ6LLgNcAwyvSNRmZtYbeZZ1zUT1Bbnb9w/LLePxwCkR8WhEPAisC5wOrAzc\nI6n94uy5wJ3AF+oeuZmZWTdphhbyFOCg4g5Jg4DVgcdIY8j7Vj4pIt4itYSvkTQf2CuXnwf8B/BX\nSd+JiFM6euGxY09c8HjYsDba2tq6/m7MzHqZF+f8gxfffqLRYXSoHO3jJkjIEfFXSadIOjwiLpfU\nFzgDOBuYQ5XPUtIOwN8j4lVJSwMfJXVdAygi5uS1RG+T9HxEXFjttY8//oS6vCczs95k1f7rsWr/\n9RZsT3vj5gZGU17N0GUNcABwiKRpwIvAvIg4NR+r1p29HjBR0oOk8edJEfGHYvmIeAXYE/iepH3q\nGr2ZmTWvkkyzbngLGSAingb2A5C0HfAbSVtGxERgYpXylwGXdVDXoMLjWaTkbWZmvdTi3g+5UZoi\nIRdFxN2kCVtmZmZdV4583DRd1mZmZr1a07WQzczMulNJGshOyGZm1uJKkpGdkM3MrMWVIyN7DNnM\nzKwJuIVsZmYtrRztYydkMzNrdSXJyE7IZmbW0kqSjz2GbGZm1gzcQjYzs9bm+yGbmZlZrdxCNjOz\nllaSBrJbyN1t4sT33ZyqaU2YOKHRIdTMsXa/ssQJcNtt5fm7KtN3wItz/tHoEEpN0h6SpkqaJum4\nKseXljRO0nRJd0lau7P6nJC7mb846sOxdr+yxAlw2+23NTqEmpXpO+DFt59odAilJakPcA6wO7Ax\nMFLSRhXFjgJejoj1gTOBH3VWpxOymZm1NEld+unAtsD0iJgREXOBccB+FWX2Ay7Jj38H7NpZnE7I\nZmZmi28wMLOwPSvvq1omIuYBr0pauaMKFRHdHWQpSOqdb9zMrAdERFNMpZL0T2BIF6t5PiLWqKj3\nYGC3iPhi3j4c2CYi/rtQ5pFc5pm8/Xgu80q1F+m1s6yb5ZfFzMzqJyLWqVPVs4DiJK21gGcqyswE\nPgQ8I6kvMKijZAzusjYzM1sSk4ChkoZIWhoYAfyxosx1wBH58SHALZ1V2GtbyGZmZksqIuZJGgXc\nRGrcXhARj0oaA0yKiOuBC4DLJE0HXiIl7Q712jFkMzOzZuIu6zqTtGKjY2h16uS6hGaQx47MzDrl\nhFxHkrYHTpLUJ19E3tQkbSlppUbHUStJwyStHU3czSNpB+BMZY2OZ1F8Atm7STpN0lqNjqO3avok\nUXLrAAMiYj5NfEvOnCv6A1ew8KzBppXj/TawWqNjqaZwArYNMCeyRsa0KJK2BR6R9AlJpZlfIum8\nfMlJ05N02KKWT2wUSQOB7Xj/TGHrIU7IdSDpA/nhfKAfLLgovCnlRDEPeBPocEp+k5kHLAcs06S9\nD4Py/9+hPJMn+wHLk5b726YMXe2SLgE+QJrN2tQkfRK4HNhf0vqNjqeKZYE1gNXL0JvTiprxi6zU\nJA0BvidpD2A28Fbev3ShTNN87pK2kbRSXvrtJWBO3r9UM/5R5tbbvjne14A3ImJ+M8UqaR3gckkb\nAi8Cq+b9TRNjBx4CLgaeBX4ArCNpHUmDOntSo+S4+kfE/hHxWh5y2V7Sss30NwYL/u1nAVOAzUhJ\nee3CsUbG9gtJB0bEi8BcYH5ERPGErNEx9hZlOXMvhdyN+i9Sl8/HgVWAQXnB8XmSniR95h8AZjQs\n0IV9BdhU0qdI3eorAS9ExLuNDatDawOnSHoHeJR00kOzdAfnL64XgLuAMaTk1v5vvbKkNyLinXwS\n1PDeCElrRMRzeXNpYAAp7r2B35BWOBoOvN6QADsnYCNJmwLbk673fBf4J+lyk6a5I0X+/Zwq6Qrg\nQdI1qftIWgW4Hri/geH9DbhY0mzgZiDykMX8QpmlSMna6siXPXWT3CIeDpxO+lI4mvRHtwHwOBCk\n1ucKwBvAfhHxUkOCBSR9FJgWEe9K+hXwUWB14C85ztdJiWUg8EBE3NyoWAEkbQ08FRH/knQgMBb4\nCHANKek9T+pyfRe4MyL+0oAYdyUlhlNJJzaHkFqaqwJXAjsAL+effsCnIuLtno6zXY73f4GTI+J/\n877vkBKESF/OTwGfAR5vpmEXSX1yz8goYEVSq/PzEfGWpJOAdSKi4ePKuZv67oj4dz5hv5D0+/ES\n8FfS90FbRExrQGzfAq6IiFmS9iOdgPUn3QRhCKl3523SPI3vR0R5bmNVUk3VrVNWkvYCfgzcSprA\n8xrwK9J40W+As0h3+dgNOBDYv8HJeA9SItsRICKOBiYC65GS20ukP8yPAJ8AGnqPtvz5/hoYnr+I\nrwa+CzxNatGNJ3VfDyIlwqcbEOPuwNnAVFI36r+Aq4AfklpqPycljQOBLwCfaWQyzmYDywA7Szom\n73ucdEu5q0iJ+HLSyc8yDYmwQr5ygTxREuAR4MPAUNLvK6TPfICkVXs+wvdI+g1pIYhlJCki5pC+\nD9YERpFOzP9C6r5eo+Oa6hLb+aTbBvaXtFREXAt8mpSAJwEHkP7GzgF+4WTcQyLCP134IbUq/w/Y\nMW8vDfQlnVUK+DrwU+DgRsea4xtO+hLbpcqxH5OSW/9Gx1kR7wPAx6sc2xd4GBjW4Bg3Io2/Dsvb\nfQu/CwPz78Dvge0b/XlWxL066dZw3yEl3S+TWu5/AP6jUG7VRsea47iK1I36+Sq/IxcDPyElkquA\n8xoc69HAnyr2iXQSPBuYmPd9BPhSD8c2Fvh9xb7++f+7kSZ27lPleX0a/TvQ6j9uIXfdUsA7EXGH\npAHAsaT1TCcAp0bEWaSu3y0lLd+oIPO10AL2Ii3xdoukFSVtJul/JG0XEceSxmXvbb8etVGTOQqv\nuwNwVUT8n6RBknaQdEruCrwDOB64IrdQG2U2cFtE3CZpdWCUpN8Cd5K6sC8hnVR8TVL/Rk6QkfSx\n9s8qIl4g9ersAfwD2JQ0DntwRPxW0jK53IuNiredpI+T5mfsD3xb0lHtxyJiAnAG6W+uDXgkIr6U\nn9fIyUj35Bi+JuknpN+DJ0kx7gEQEY9GxHm5XE/F2o/UQ4akttztf5ukrwK3A4cB10ravPikeK9X\nwurEk7qWkKShpBnUL5AS2BRSN+/tpLVNrwf+IukmUndl34h4o1Hxtv8xSXoY2EnS3sDhpLHtzYAt\nJG0dEd+QdA5pbOvVyKfGDbAhqfv3JWADSXuSunrfJXX5bQFcHRG/yt9j03s6wJzYlif9m+8i6TTg\nUFL3/z355wLStZ1nk34H5vR0nO2ULse7kzRp52ekscLxpM/0eVLLaHfSmPep0fgudQDyie59pBn1\nf5f0MnCJJCLiAoCIeIR0DfUNkWbgLxhn7uFY2yfrPQusL2kL0jDFWNLJ2QOknpTZkvq1x5rfQ13/\n1iStnk/CXgA2zxM51yN1Ud8ObJvD+Lmkj0fEg/WMx97PCXkJ5DHYnwCTScnhCFICbp8x+Xakhcev\nIXUFvdawYElnwaTxoXtI3WZPAmeSvox/TfqyOwz4GEBEjGpMpEn+fM+XtA0pxo8Bx5G62n8dEXdJ\n2hf4kqRLI+KaBsS4G/Aj4BsR8bzSvVHbgNNIE2Vey+U+BqwdEf/X0zFWynEeROqi3o50Cc4PSSdl\nd0bE6DzxaBs1zyzwS0njmmMj4u8AuTfqc6RF+9+MiHGSjgUuioiX8/PUgGR8KTBH0g9ICW4MKQn/\nLCJuAW6RtBywCTC1mIx7ILZzSXcm+jvpCoA3SCde3yNN7nxG0udJV4cA3Juf1+MnNb2Zu6wXUz6r\nPB34Yv75G+lLeEJE/DYi3srJ+BBgZ1Irr2FyK+5npEsWDiatHnYx8ImceO+OiHdI3VgfkDSgwV2q\ne5Mmk/xnRDwfETMiTTr7dHu8uehypNngPb54RU7GFwCfzV3/awJzI+IX+ac9GX+W9OU7q6dj7MT1\npESxPPBv0vj2a8BaklYgDbeMaZJkPIAU55bA3pLaJ20REX8jdV+fpHQ54cbtyTgf79GenUKsWwEH\nkX4v9ySN0x+s91Y+25K0AEdPxva/+TWPJk183BG4OCI+HxETIqJ9Za5Pk1rPCz4/J+Me1uhB7LL9\nAOOAywrbHwPO571LyD5I6p56hPQl0chYNyNNgmmfbLQ96ex4m4pyXyR1pTUsXlLLfXVScjg17xuS\nP+/1C+WWBY4kteo3bUCcy5CS2GRSt/5AUmton0KZjwDHNMnvwJ45lk0q9h9AYXIfsEoj4+wk/qNI\nwxHnA98ANqg4/ghwafH3qEli/RYp+a0G3EA6if8L8KsejunTpKG17fP2wPy7+/G8PYB0kn5dMbZG\nfo69+cct5BoprQD0adJs2dUkjc6HDiGNHbe3Kp8j/VEeFBFTej7ShTxBmrzxJYCIuIt0SdAHACSt\nkrswP0Nq7TUs3kheIHX/D8sTTC4C7oiI6TnepUnjcQcCR0TEwz0Zo6QdgZHAY6Reh9+TFnS4MCKK\nSze+RPriO7iRn6nSalV7At8nrR53qaTVJS0XEX8gtZR/LGlkNPAyvEqSdlZexSrSGPEVpMV2NiO1\nNtfP5XYF/hwRn8vbfSJnkyaI9SPA/5B6pg4k/b6cFKm3pydX67uPNHv+m5I2iYg3SWsMzM7H+5BO\n1CcVY+vpz9ESLwxSgzxeeRLpEps3gN+SWkkrklqgu0VaYKNvNMHiCUrXX86PiJdzEruQdAnODNJk\nqUMiT9iRtBowLwrdfQ2Idzhp9vf9pAkm65JaxsUv26XyZzwQWDp6uEs1j2ufSro0bAaplfFF4HOk\nxDtNaanBiLRgRcN+F/L4aeTHewKjyd27pB6I5YBTIuKfeYjgONLn/+9GfxHnE7GzSYuS3EiaEHk4\naYb1ZNKs+umkS5uejPcmKzZiAlctsT4B/C4iHis8T/X+nPMEw1VICfcZ0rDJQcBg4IyIuLBQdulI\nw1YeM24wt5AXQWlpu68Ch0XEZ0hdpvNJX3L/Jv0h9mmiZLwX8Gfgl5JOzn9oXyadqX+FlDzezpN3\niIh/NTgZ706aYNbekjiKlJiPJC3peUCOs/2E580GJOM20gIJX4qIyyLitoh4nXTycCJwhqRP5H//\n9rG3Rv4uLBhXj4gbSKttHR0RX8iPDweulnQK6Xd4t4h4o9HJOPsb6ffhOXJPCOk647NI3aunkSak\nfbSYOBqURGqJdRtgoRtJ9EAyvojUQr+SNCfgENLQ2iTSjPrbc7mlcjzvFGJzMm4gz7JetHdJSXgj\nSU8Bw0jjQk+QlpbbjTRb8RTSkogNk1tx3wVOJrXijpW0bKRl+/6TdCJxkaTPRwMvv2mntMb3DcDw\nSNfwbkdaROUPEfHHPLlstKT+EfGbBia5LYGzozBTWtKPSF/A55GWn/yhpGMj4t4Gxdge16eAIyU9\nSJrJew3pM91LaXnE/yZd2vQWaXLP4xExu8MKe1hETM4TpLYjda3OBK4lJZgPR8T1kr4WETMbGSc0\nZ6z5339wROxW2HcfafhnHukE8seSfhxefavpuIW8CJFmzJ5FulTkJtJ44V6kP7wXSWNDH6QBs32L\nJK1Mahn/ONIyeEsDnyT98Z2fz4KPIs0EvbDjmnqGpC1JXxB/JM3+JCLupjDGnd/HKcBXJS3f07O/\nC6+3HoX7Ludu4DVI3cCHk/79LyJdy9sw+YTsZNK1xgOB/SRtRVrsZUfgauALEXFHRNwP/DwiGj4D\nXNLJkrbOvVFExJ2k1e9eJl2pcB3pd/n2fHxmfl6PXw1Qklhn5dfsl4d6ZpJOHrcHXiX9fmzdg/FY\nrbpzhlgr/5DWSD4d2Luw71rS5UMNjy/H82nSbOnNSTM6xwAfIn1hjMtlBgJrNjjOPUhjbIeQxosv\nJo0Jnk5K0P0ryi/X4Hh3zZ/nVnm7H2kcG1KPxKHk5TIbGOPKpB6QffL2h0hdlgfl7c1JJ5QfbGSc\nVeLegnT52g2kqxNGFY5tnn8nzgDWdaw1xbhR/tvarrBvYP7/paQrFzyDukl/3EKuUaRxy1uAgyTt\nlid6fYgG3MigIxHxJ1JL/gHgrxExOtLZ8a6kmeGrRBqDfabTiuooj8eeTRrTvCoiniQttD+H98a4\n57SPcQNExL8bE+0Cd5PGC0dI2jYi5ka6heJI0m0K74kGzx+INA9gH+BUSYPyv/tcYNXcOptBWonr\nE41oWXYkIiaTWu4i/X19XtKP8+z/h0hDAu0zgRuqJLE+RrqBxaFKq4QRaWY1pMsKTyPNvG/0sqJW\nhWdZLwal9Z0/R5qtOAf4VjTh8nJ5HOkc0rWGr+bx46OB3aOBy3fm2I4hzer+mQpLB+bZ0z8nfdkd\nFT24ilEtJA0mdfnvQjrhmU1aaGX/yCtINYPcnX4WabLhmqS7Ss3Oxw4D7sonQQ0naZlIEww/QloD\nflQ+GZtOGuOeS5oZ/lSkLnbHWlusHyRNRN2Q1Jpvn3y4Eqm37MIozPq25uGEvASUbhKhSDNtm1L+\nYj6dlORGAF+JtN5vo+JRRISks4HXIuL7lZd/KF1fejowOyJGNirWjkhalrQS06dIPSMTIl8j3UyU\nbrxxE7BGRLwgaUBEvNXouNpJOpU0Jr8U6TrZy4BzSV3smwGfjIg2Sd8GXonCzReih7+wyhRrUZ5T\nshvp8swHgbci3TzGmpgTcgvL15heDWwZjV+kBABJu5DGXY+LiPuUF0iIdO3uF0jXdM6OiIZOkCq7\nfEJ2BrBzpAVXmkK+JGcVUit+EO+dND5NWlTjoYjYonERvqdMsXakeI1x3vZ1xk3Mlz21sEiXXazY\nTK0jUpfZHaQxLiLiPgBJI0jdbOOdjLsuIm5QWhRmvNINLqKRLTbo9JKcS0ljsv9NmgVMvtStkXfG\nKk2si7Bg6Ce32p2Mm5hbyNbjCuOxu5LGt+aQxmMPbmS3eitSWiaz0ZPigAVJbmREHCmpH+kk4V1J\na5FuenEHqZv1oxHxrmO13sYtZOtxEfG0pNNJLY1Pku4du29ETGtsZK2nWZJxNhPYStJ2ka45R9LA\niJj1/9u7txCrqjiO499fF7yPSSVk0QUbsmKKDEQousmERUYJBmFSGFFGUElYkOCLMJVv9ab0YJRh\nD0kzNZYYhF28DaPOEBnR1IsPRW82mlHz72H/jxzmzBmP0zCzz/D7PB3W/u+91j4v//Pf66y9JPVS\nLCU6WpIE10xjtSnCFbKZTYhcZrOB4qUq23MZUeXYHoqt/3ZERPdkz3U201ht6vA6ZDObEDmH/R4w\nSLH71FpJbZJ2UbxZ7gTwc8ZOaoJrprHa1OEK2cwmVDMtyWmmsVrzc0I2s0nRTEtymmms1rz8yNrM\nJkszLclpprFak3KFbGZmVgKukM3MzErACdnMzKwEnJDNzMxKwAnZzMysBJyQzYaR9K+kXkn9knZK\nmv4/rnW3pK78vELShlFi50paN4Y+NuU+043GT+qe2GY2Midks1qDEbE4Itoolrs8NzwgX63YqACI\niK6IeGuUuHnA8+c10rHx0gqzEnJCNhvd18D1kq6RdFzSdkn9wFWS2iV9J6knK+mZAJKWS/pBUg+w\nsnIhSU9Keic/z5f0saSjko5IWgp0AAuzOn8z416RdCjjNlVd63VJP0raB9ww0sDr9AGgPD5L0t4c\n/zFJD2f7TEmf5jl9klZl+xuSvs/rjfbDwszGwLs9mdWqJKyLgAeA3dneCqyJiMOSLgU2Assi4nQ+\niieGbiwAAAJNSURBVF6fu1htBe6JiAFJO4ddu1Kdvg18FRErs9qeDbwG3BwRi7P/dqA1IpZkTKek\nO4FTwGPALRTvVe4Feka4j5H6qB7DX8AjEfFn3s8BoBNYDpyIiIdyHHMkzcvYRdnWcj5fqJmdmxOy\nWa0ZucUeFBXyu8CVwK8RcTjblwI3Ad9msrsY2A8sAgYiYiDj3geeGaGP+4A1cHYjg5P53uRq9wPt\nORYBsyh+FLQAuyLiDHBGUmed+6jpY9hxAR2S7gKGgAWS5gP9wBZJHcBnEfGNpAuB05K2Ad0UewKb\n2ThyQjardapSpVbklPFgdROwJyJWD4u7tcE+GpnHFdAREduG9fFig+efK2Y1cBlwW0QMSfoFmB4R\nP0m6HXgQ2Cxpb0RslrQEWAasAl7Iz2Y2TjyHbFar3h+2qtsPAHdIWgggaYakVuA4cK2k6zLu8TrX\n+pL8A5ekCyTNoahg51TFfAGslTQr4xZIuhzYBzwqaVqet6LBPiqPrCv3MRf4PZPxvcDVGXsFcDoi\ndgBbgMU5P35JRHwOrKd4XG5m48gVslmtepXl2faI+EPSU8CHkqblsY1ZXT4LdEsapHjkPXuEa70E\nbJX0NPAPsC4iDuafxPqA3RHxqqQbgf1ZoZ8EnoiII5I+AvqA34BDdcZb0wdwsOo+PgC6JB2jmIM+\nnu1tFI+sh4C/87wW4JOqJWAv1+nTzMbIm0uYmZmVgB9Zm5mZlYATspmZWQk4IZuZmZWAE7KZmVkJ\nOCGbmZmVgBOymZlZCTghm5mZlYATspmZWQn8B3jjqbjgnetNAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f6c6833a860>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_32test_std[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_32_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
